/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

#include <QApplication>
#include <QTranslator>
#include <QProcess>
#include <QSettings>
#include "BurnDlg/BurnDlgFaction.h"
#include "BurnToolCommon/Global.h"
#include "BurnToolCommon/StringClass.h"
#include "BurnCtrl/CmdCtrl.h"
#include "BurnCtrl/BurnCtrl.h"
#include "upgrade/UpgradeDlg.h"
#include "BurnDlg/BurnDlgSle.h"

using namespace UpgradeDlgClass;

namespace  {
    const QString COMMAND_LINE_SERVER = "-server:";
    const QString COMMAND_LINE_COM = "-com:";
    const QString COMMAND_LINE_BAUD = "-baud:";
    const QString COMMAND_LINE_SIGNAL_BAUD = "-signalbaud:";
    const QString COMMAND_LINE_FLASH_BOOT = "-flashboot:";
    const QString COMMAND_LINE_ROM_BOOT = "-romboot";
    const QString COMMAND_LINE_ONLY_BURN = "-onlyburn:";
    const QString COMMAND_LINE_BIN = "-bin:";
    const QString COMMAND_LINE_INFORMAL = "-informal";
    const QString COMMAND_LINE_ERASE_MODE = "-erasemode:";
    const QString COMMAND_LINE_2MS = "-2ms";
    const QString COMMAND_LINE_SHOW = "-show";
    const QString COMMAND_LINE_CLEAR_LOG =  "-clearlog";
    const QString COMMAND_LINE_FOCEREAD = "-forceread:";
    const QString COMMAND_LINE_TIMEOUT = "-timeout:";
    const QString COMMAND_LINE_CONSOLE = "-console";
    const QString COMMAND_LINE_ONLY_ERASE_ALL = "-onlyeraseall";
    const QString COMMAND_LINE_RESET = "-reset";
    const QString COMMAND_LINE_IP_ADDR = "-ipaddr:";
    const QString COMMAND_LINE_IP_PORT = "-ipport:";
    const QString COMMAND_LINE_EXPORT_START = "-export";
    const QString COMMAND_LINE_EXPORT_TARGET = "-target:";
    const QString COMMAND_LINE_EXPORT_ADDR = "-addr:";
    const QString COMMAND_LINE_EXPORT_SIZE = "-size:";
    const QString COMMAND_LINE_DFU_VID = "-vid:";
    const QString COMMAND_LINE_DFU_PID = "-pid:";
    const QString COMMAND_LINE_DFU_PATH_ID = "-devicepathid:";
    const QString COMMAND_LINE_DFU_LOCATION = "-usblocation:";
    const QString COMMAND_LINE_DFU_USAGE = "-usage:";
    const QString COMMAND_LINE_DFU_USAGEPAGE = "-usagepage:";
    const QString COMMAND_LINE_BS25_DFU = "-bs25dfu";
    const QString COMMAND_LINE_BS21_DFU = "-bs21dfu";
    const QString COMMAND_LINE_DFU = "-dfu";
    const QString COMMAND_LINE_CHIPTYPE = "-chiptype:";
    const QString COMMAND_LINE_JLINK_PATH = "-jlinkpath:";
    const QString COMMAND_LINE_3X = "-3x";
    const QString COMMAND_LINE_READ_EFUSE = "-readefuse";
    const QString COMMAND_LINE_START_BIT = "-startbit:";
    const QString COMMAND_LINE_BIT_WIDTH = "-bitwidth:";
    const QString COMMAND_LINE_AUTO_DFU = "-autodfu";
    const QString COMMAND_LINE_HID_DFU = "-hiddfu";
    const QString COMMAND_LINE_PACKAGE_SIZE = "-packagesize:";
    const QString COMMAND_LINE_SWITCH_AFTER_LOADER = "-switchafterloader";
    const QString COMMAND_LINE_SLE = "-sle";
    const QString COMMAND_LINE_SLE_ADDRESS = "-address:";
    const QString COMMAND_LINE_GET_HID_DEVICE = "-gethiddevice";
    const QString COMMAND_LINE_SLE_ADDRESS_TYPE = "-addresstype:";
    const QString COMMAND_LINE_BURN_INTERVAL = "-burninterval:";
    const int PERIOD_VALUE_TWO = 2;
}

static bool ProcessCommandline(QStringList strCmd);
static void ParseOtherParams1(const QString &cstrParamLower, bool &isCmdValid, bool &isReopenOutput);
static void ParseOtherParams2(const QString &cstrParamLower, bool &isCmdValid, bool &isReopenOutput);
static void ParseOtherParams2Sub(const QString &cstrParamLower, bool &isCmdValid, bool &isReopenOutput);
static void ParseOtherParamsDfuCom(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput);
static void ParseOtherParamsDfu1(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput);
static void ParseOtherParamsJlink(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput);
static void ParseOtherParamsReadEfuse(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput);
static void ParseOtherParamsSle(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput);
static void ParseOtherParamsBurnInterval(const QString &cstrParamLower, bool &isCmdValid);
static void OutputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg);
static void SetLanguage();

static void SetChipTypeInConfig(const QString &configPathFile)
{
    int chipType = 0;
    if (QFile(configPathFile).exists()) {
        QSettings cfg1(configPathFile, QSettings::IniFormat);
        chipType = cfg1.value(DLG_CONFIG + "/" + "CHIP_TYPE").toString().toInt();
    }
    if (chipType != 0) {
        QSettings cfg2(Global::GetAppConfigPath() + "\\config_chip_type.ini", QSettings::IniFormat);
        cfg2.setValue("ChipType/CurrentChipTypeId", QString::number(chipType));
    }
}

static void HandleTranslator()
{
    QSettings cfg(Global::GetAppConfigPath() + "\\config_all_chip_type.ini", QSettings::IniFormat);
    int translate = cfg.value("AHHCHIPTYPECONFIG/TRANSLATE").toInt();
    if (translate == 1) {
        QTranslator *translator = new QTranslator();
        translator->load(":/CNBurnTool.qm");
        qApp->installTranslator(translator);
    }
}

static void ShowWhenNoArg(UpgradeDlg *&dlgu, BurnDlg::BurnDlg *&dlgb)
{
    BurnDlg::BurnDlgFaction faction;
    if (Global::currentChipTypeId == ChipType::UPGRADE) {
        dlgu = new UpgradeDlg();
        if (dlgu != nullptr) {
            dlgu->show();
            dlgu->setWindowTitle(QObject::tr("Upgrade"));
        }
    } else if (Global::currentChipTypeId == ChipType::SLEBS2X ||
               Global::currentChipTypeId == ChipType::SLE2982) {
        BurnDlg::BurnDlgSle *dlg = new BurnDlg::BurnDlgSle();
        dlg->show();
        dlg->setWindowTitle(QObject::tr("BurnTool"));
    } else {
        dlgb = faction.GetBurnDlg(Global::currentChipTypeId);
        if (dlgb != nullptr) {
            dlgb->show();
            dlgb->setWindowTitle(QObject::tr("BurnTool"));
        }
    }
    OperationLog optLog;
    optLog.RecordFile(QByteArray("软件启动。。。"));
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QString configPathFile = DataConvertor::GetBurnToolConfigPathNew();
    SetChipTypeInConfig(configPathFile);

    Global::ReadCfg();
    Global::ReadAllChipType();
    qInstallMessageHandler(OutputMessage);
    UpgradeDlg *dlgu = nullptr;
    BurnDlg::BurnDlg *dlgb = nullptr;
    HandleTranslator();

    if (argc <= 1) {
        ShowWhenNoArg(dlgu, dlgb);
    } else {
        QStringList commandLine;
        commandLine.clear();
        for (int i = 1; i < argc; i++) {
            commandLine.push_back(QString::fromLocal8Bit(argv[i]));
        }
        ProcessCommandline(commandLine);
    }
    int ret = a.exec();
    if (ret == QAPP_EXIT_VALUE) {
        if (QFile(configPathFile).exists()) {
            Global::ReadCfg();
            QSettings cfg1(configPathFile, QSettings::IniFormat);
            cfg1.setValue(DLG_CONFIG + "/" + "CHIP_TYPE", QString::number(static_cast<int>(Global::currentChipTypeId)));
        }
        QProcess::startDetached(qApp->applicationFilePath(), QStringList());
    }
    if (dlgu != nullptr) {
        delete dlgu;
    }
    if (dlgb != nullptr) {
        delete dlgb;
    }
    return ret;
}

static void SetLanguage()
{
    QSettings cfg(Global::GetAppConfigPath() + "\\config_all_chip_type.ini", QSettings::IniFormat);
    int translate = cfg.value("AHHCHIPTYPECONFIG/TRANSLATE").toInt();
    if (translate == 1) {
        QTranslator *translator = new QTranslator();
        translator->load(":/CNBurnTool.qm");
        qApp->installTranslator(translator);
    }
}
static bool ProcessCommandline(QStringList strCmd)
{
    bool isReopenOutput = false;
    bool isCmdValid = false;
    for (int i = 0; i < strCmd.size(); ++i) {
        QString cstrParam = strCmd[i];
        QString cstrParamLower = cstrParam.toLower();
        ParseOtherParams1(cstrParamLower, isCmdValid, isReopenOutput);
        if (!isCmdValid) {
            break;
        }
    }
    if (!isReopenOutput) {
        int ret = AttachConsole(-1);
        if (ret != 0) {
            FILE *fp = nullptr;
            freopen_s(&fp, "CONIN$", "r+t", stdin);
            freopen_s(&fp, "CONOUT$", "w+t", stdout);
        }
    }
    if (isCmdValid) {
        if (Global::currentChipTypeId == ChipType::SLEBS2X ||
            Global::currentChipTypeId == ChipType::SLE2982) {
            UINT ret = CmdCtrl::GetInstence()->SleInitConfig();
            return false;
        }
        UINT ret = CmdCtrl::GetInstence()->InitConfig();
        if (ret != ERR_SOP_SUCCESS) {
            return false;
        }
        ret = CmdCtrl::GetInstence()->StartProc();
        if (ret != ERR_SOP_SUCCESS) {
            return false;
        }
    } else {
        CmdCtrl::GetInstence()->PassParamErrorHint();
    }
    return FALSE;
}

static void ParseOtherParams1(const QString &cstrParamLower, bool &isCmdValid, bool &isReopenOutput)
{
    if (cstrParamLower.contains(COMMAND_LINE_CHIPTYPE)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetChipType(Global::ChipTypeStringToId(strInfo));
        isCmdValid = true;
        CmdCtrl::GetInstence()->SetIsChipType(true);
    } else if (cstrParamLower.contains(COMMAND_LINE_COM)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetComNum(DataConvertor::Str2U32(strInfo, 0xa));
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_BAUD) ||
        cstrParamLower.contains(COMMAND_LINE_SIGNAL_BAUD)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetBaud(DataConvertor::Str2U32(strInfo, 0xa));
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_FLASH_BOOT)) {
        CmdCtrl::GetInstence()->SetBootType(BOOT_LOADER);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_ROM_BOOT)) {
        CmdCtrl::GetInstence()->SetBootType(BOOT_ROM);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_ONLY_BURN)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetAllowBurnFile(strInfo);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_3X)) {
        CmdCtrl::GetInstence()->SetChipType(ChipType::SPARTA);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_PACKAGE_SIZE)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetPackageSize(strInfo.toUInt());
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_SWITCH_AFTER_LOADER)) {
        CmdCtrl::GetInstence()->SetSwitchAfterLoader();
        isCmdValid = true;
    } else {
        ParseOtherParams2(cstrParamLower, isCmdValid, isReopenOutput);
    }
}

static void ParseOtherParams2(const QString &cstrParamLower, bool &isCmdValid, bool &isReopenOutput)
{
    if (cstrParamLower.contains(COMMAND_LINE_BIN)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetBinPath(strInfo);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_INFORMAL)) {
        CmdCtrl::GetInstence()->SetFormal(false);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_ERASE_MODE)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetEraseMode(strInfo.toInt());
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_SHOW)) {
        CmdCtrl::GetInstence()->SetShow(true);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_CLEAR_LOG)) {
        CmdCtrl::GetInstence()->SetOnlyBurnToolLog(true);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_FOCEREAD)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetForceRead(true);
        CmdCtrl::GetInstence()->SetForceReadTime(DataConvertor::Str2U32(strInfo, 0xa));
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_TIMEOUT)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetConnectTimeout(DataConvertor::Str2U32(strInfo, 0xa));
        isCmdValid = true;
    } else {
        ParseOtherParams2Sub(cstrParamLower, isCmdValid, isReopenOutput);
    }
}

static void ParseOtherParams2Sub(const QString &cstrParamLower, bool &isCmdValid, bool &isReopenOutput)
{
    if (cstrParamLower.contains(COMMAND_LINE_CONSOLE)) {
        isReopenOutput = true;
        setvbuf(stdout, nullptr, _IONBF, 0);
    } else if (cstrParamLower.contains(COMMAND_LINE_ONLY_ERASE_ALL)) {
        CmdCtrl::GetInstence()->SetOnlyEraseAll(true);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_RESET)) {
        CmdCtrl::GetInstence()->SetResetAfterBurn(true);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_IP_ADDR)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetIpAddr(strInfo);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_IP_PORT)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetIpPort(DataConvertor::Str2U32(strInfo, 0xa));
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_EXPORT_START)) {
        CmdCtrl::GetInstence()->SetExportAfterBurn(true);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_EXPORT_TARGET)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetExportTarget(strInfo);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_EXPORT_ADDR)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetExportAddr(strInfo);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_EXPORT_SIZE)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetExportSize(strInfo);
        isCmdValid = true;
    } else {
        ParseOtherParamsReadEfuse(cstrParamLower, isCmdValid, isReopenOutput);
    }
}

static void ParseOtherParamsReadEfuse(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput)
{
    if (cstrParamLower.contains(COMMAND_LINE_READ_EFUSE)) {
        CmdCtrl::GetInstence()->SetIsReadEfuse(true);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_START_BIT)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetStartBit(strInfo);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_BIT_WIDTH)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetBitWidth(strInfo);
        isCmdValid = true;
    } else {
        ParseOtherParamsDfuCom(cstrParamLower, isCmdValid, isReopenOutput);
    }
}

static void ParseOtherParamsDfuCom(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput)
{
    if (cstrParamLower.contains(COMMAND_LINE_BS25_DFU)) {
        CmdCtrl::GetInstence()->SetChipType(ChipType::USBBS25);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_BS21_DFU)) {
        CmdCtrl::GetInstence()->SetChipType(ChipType::USBBS2X);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_DFU)) {
        CmdCtrl::GetInstence()->SetChipType(ChipType::USBBS25);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_DFU_VID)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetDfuVid(DataConvertor::Str2U32DecHex(strInfo));
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_DFU_PID)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetDfuPid(DataConvertor::Str2U32DecHex(strInfo));
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_DFU_PATH_ID)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetDfuPathID(strInfo);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_DFU_LOCATION)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetDfuLocation(strInfo);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_DFU_USAGE)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetDfuUsage(DataConvertor::Str2U32DecHex(strInfo));
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_DFU_USAGEPAGE)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetDfuUsagePage(DataConvertor::Str2U32DecHex(strInfo));
        isCmdValid = true;
    } else {
        ParseOtherParamsDfu1(cstrParamLower, isCmdValid, isReopenOutput);
    }
}

static void ParseOtherParamsDfu1(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput)
{
    if (cstrParamLower.contains(COMMAND_LINE_AUTO_DFU)) {
        CmdCtrl::GetInstence()->SetIsHidDfu(false);
        CmdCtrl::GetInstence()->SetIsAutoDfu(true);
        CmdCtrl::GetInstence()->SetChipType(ChipType::USBBS25);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_HID_DFU)) {
        CmdCtrl::GetInstence()->SetIsAutoDfu(false);
        CmdCtrl::GetInstence()->SetIsHidDfu(true);
        CmdCtrl::GetInstence()->SetChipType(ChipType::USBBS25);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_GET_HID_DEVICE)) {
        CmdCtrl::GetInstence()->SetIsGetHidDevice(true);
        isCmdValid = true;
    } else {
        ParseOtherParamsJlink(cstrParamLower, isCmdValid, isReopenOutput);
    }
}

static void ParseOtherParamsJlink(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput)
{
    Q_UNUSED(isReopenOutput);
    if (cstrParamLower.contains(COMMAND_LINE_JLINK_PATH)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetJLinkPath(strInfo);
        isCmdValid = true;
    } else {
        ParseOtherParamsSle(cstrParamLower, isCmdValid, isReopenOutput);
    }
}

static void ParseOtherParamsSle(const QString &cstrParamLower, bool &isCmdValid, const bool &isReopenOutput)
{
    Q_UNUSED(isReopenOutput);
    if (cstrParamLower.contains(COMMAND_LINE_SLE)) {
        CmdCtrl::GetInstence()->SetChipType(ChipType::SLEBS2X);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_SLE_ADDRESS)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetSleAddr(strInfo);
        isCmdValid = true;
    }  else if (cstrParamLower.contains(COMMAND_LINE_SLE_ADDRESS_TYPE)) {
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1);
        strInfo = strInfo.trimmed();
        CmdCtrl::GetInstence()->SetSleAddr(strInfo);
        isCmdValid = true;
    } else {
        ParseOtherParamsBurnInterval(cstrParamLower, isCmdValid);
    }
}

static void ParseOtherParamsBurnInterval(const QString &cstrParamLower, bool &isCmdValid)
{
    if (cstrParamLower.contains(COMMAND_LINE_2MS)) {
        CmdCtrl::GetInstence()->SetPeriod(PERIOD_VALUE_TWO);
        isCmdValid = true;
    } else if (cstrParamLower.contains(COMMAND_LINE_BURN_INTERVAL)) {
        QTextStream qout(stdout);
        MyStringClass::StringClass stringClass;
        const int idxColon = cstrParamLower.indexOf(':');
        QString strInfo = cstrParamLower.mid(idxColon + 1).trimmed();
        int burnInterval = strInfo.toInt();
        if (burnInterval < MIN_BURN_INTERVAL || burnInterval > MAX_BURN_INTERVAL) {
            qout << stringClass.GetBurnIntervalValueTips();
            isCmdValid = false;
            return;
        }
        CmdCtrl::GetInstence()->SetPeriod(burnInterval);
        isCmdValid = true;
    } else {
        isCmdValid = false;
    }
}

static void OutputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    static QMutex mutex;
    mutex.lock();

    QString text;
    switch (type) {
        case QtDebugMsg:
            text = QString("Debug:");
            break;

        case QtWarningMsg:
            text = QString("Warning:");
            break;

        case QtCriticalMsg:
            text = QString("Critical:");
            break;

        case QtFatalMsg:
            text = QString("Fatal:");
            break;
        default:
            text = QString("Other:");
            break;
    }

    QString contextInfo = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);
    QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    QString message = QString("%1 %2 %3 (%4)").arg(text).arg(contextInfo).arg(msg).arg(currentDateTime);

    QString filePath = QApplication::applicationDirPath() + "/log.txt";
    QFile file(filePath);
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream textStream(&file);
    textStream << message << "\r\n";
    file.flush();
    file.close();

    mutex.unlock();
}
